package com.hst.web.base.proxy;

import java.sql.Timestamp;
import java.util.*;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.hst.core.Page;
import com.hst.core.ServiceContext;
import com.hst.core.dao.IORDao;
import com.hst.core.dao.ISQLDao;
import com.hst.core.dao.ORQuery;
import com.hst.core.dao.ORQuery.Op;
import com.hst.core.meta.MetaData;
import com.hst.core.meta.MetaRepository;
import com.hst.core.meta.proxies.DefaultDataProxy;
import com.hst.web.auth.po.User;
import com.hst.web.base.entity.TAccountIdentity;
import com.hst.web.base.entity.TCompanyDept;
import com.hst.web.base.entity.TCompanyEmployee;
import com.hst.web.base.entity.TCompanyInfo;
import com.hst.web.base.entity.TContractorInfo;
import com.hst.web.base.entity.TDeptEmployee;
import com.hst.web.base.entity.TEmployeeContractorDept;
import com.hst.web.base.entity.TEmployeeOperate;
import com.hst.web.base.entity.TVehicleInfo;
import com.hst.web.base.service.EmployeeService;
import com.hst.web.base.service.UserRoleService;
import com.hst.web.base.ui.CompanyEmployee;
import com.hst.web.base.ui.EmployeeIdentify;
import com.hst.web.common.utils.ConstantUtil;
import com.hst.web.common.utils.PapersNumberUtils;
import com.hst.web.sys.entity.TRole;
import com.hst.web.sys.entity.TUser;
import com.hst.web.sys.entity.TUserRole;

public class CompanyEmployeeProxy extends DefaultDataProxy {

    /**
     * 发证状态：未发证
     */
    private static final String PUSHFLAG_NOT = "0";

    /**
     * 人员操作状态：离职
     */
    private static final String OPTYPE_DEPART = "2";

    @Autowired
    IORDao dao;

    @Autowired
    ISQLDao sql;

    @Autowired
    MetaRepository mr;
    
    @Autowired
    EmployeeService employeeService;

    @SuppressWarnings("unchecked")
    @Override
    public Page<?> list(Map<String, ?> query, int pageIdx) {
        UserRoleService.addCompanyEmpParam((Map<String, Object>) query);
        return sql.list("employee.list-company-employee", query, pageIdx, Page.getPageSize());
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<?> list(Map<String, ?> query) {
        UserRoleService.addCompanyEmpParam((Map<String, Object>) query);
        return sql.query("employee.list-company-employee", query);
    }

    @Override
    public Object save(MetaData data) throws Exception {
		User u = (User) ServiceContext.getInstance().getUser();
        CompanyEmployee e = (CompanyEmployee) data;
        //如果证件类型为身份证"01",则将证件号号码中的"x"改为"X",进行保存
        if ("01".equals(e.getPapersType())) {
        	String papersNumber = e.getPapersNumber();
        	e.setPapersNumber(papersNumber.replace('x', 'X'));
        }
        
        if (e.getEmployeeIdentify() != null && data.getOp() != MetaData.OP_NEW) {
            EmployeeIdentify ei = e.getEmployeeIdentify();
            int op = ei.getOp();
            BeanUtils.copyProperties(ei, e);
            ei.setOp(op);
            mr.getMetaProxy("employee-identify").save(ei);
            e.setIdentifyFlag(ConstantUtil.IDENTIFYFLAG_OK);
        }
        Boolean isNew = (e.getOp() == MetaData.OP_NEW);
        String linkId = e.getLinkId();
        String deptCode = e.getDeptCode();

        String companyCode = e.getCompanyCode();
		if (StringUtils.isEmpty(companyCode)) {		//如果企业代码为空则使用
			companyCode = u.getCompanyCode();
		}
        if (StringUtils.isNotEmpty(e.getDeptCode())) {
        	TCompanyDept companyDept = dao.get(TCompanyDept.class, deptCode);
        	if (companyDept != null) {
        		companyCode = dao.get(TCompanyDept.class, deptCode).getCompanyCode();
        	}
        }

        PapersNumberUtils.validate(e.getPapersNumber(), e.getPapersType());
        List<TCompanyEmployee> l = null;
        l = PapersNumberUtils.getEmployee(e.getPapersNumber(), e.getPapersType());
        if (l.size() > 0) {
            if (!StringUtils.isEmpty(e.getEmployeeCode()) && !l.get(0).getEmployeeCode().equals(e.getEmployeeCode())) {
                throw new Exception("该身份信息已存在在另一人员上，无法编辑。");
            }
            if (l.size() != 1
                    || (StringUtils.isEmpty(e.getEmployeeCode()) && !e.getFullname().equals(l.get(0).getFullname())))
                throw new Exception("存在相同证件号且不同姓名人员，请检查证件号是否填写错误");
            
            //员工在企业员工表或企业承包商员工表中不能重复
            List<ORQuery> query = new ArrayList<ORQuery>();
            query.add(new ORQuery(Op.eq, "employeeCode", l.get(0).getEmployeeCode()));
            if (e.getLinkId() != null) {
            	query.add(new ORQuery(Op.neq, "Id", e.getLinkId()));
            }
            List<TDeptEmployee> deptEmployeeList = dao.list(TDeptEmployee.class, query);
            if (deptEmployeeList.size() > 0) {
            	List<String> listCompany = new ArrayList<String>();
            	for (TDeptEmployee d : deptEmployeeList) {
            		TCompanyInfo c1 = dao.get(TCompanyInfo.class, d.getCompanyCode());
            		if (c1 != null) {
            			listCompany.add(c1.getCompanyName());
            		} else {			//所属企业已被删除时,做离职处理
            			employeeService.companyEmployeeResign(d);
            		}
            	}
            	if (listCompany.size() > 0) {
            		throw new Exception("企业员工在(" + StringUtils.join(listCompany, ",") + ")中已存在,请先离职！");
            	}
            }
            query.clear();
            query.add(new ORQuery(Op.eq, "employeeCode", l.get(0).getEmployeeCode()));
            List<TEmployeeContractorDept> employeeContractorDeptList = dao.list(TEmployeeContractorDept.class, query);
            if (employeeContractorDeptList.size() > 0) {
            	List<String> listCompanyContractor = new ArrayList<String>();
            	for (TEmployeeContractorDept d : employeeContractorDeptList) {
            		TCompanyInfo c1 = dao.get(TCompanyInfo.class, d.getCompanyCode());
            		if (c1 != null) {
            			listCompanyContractor.add(c1.getCompanyName());
            		} else {			//所属企业已被删除时,做离职处理
            			employeeService.contractorEmployeeResign(d);
            		}
            	}
            	if (listCompanyContractor.size() > 0) {
            		throw new Exception("承包商员工在(" + StringUtils.join(listCompanyContractor, ",") + ")中已存在,请先离职！");
            	}
            }
            
            e.setEmployeeCode(l.get(0).getEmployeeCode());
            e.setReviewStatus(l.get(0).getReviewStatus());
            e.setBeginExpirydate(l.get(0).getBeginExpirydate());
            e.setEndExpirydate(l.get(0).getEndExpirydate());
            e.setIssueNo(l.get(0).getIssueNo());
            e.setCheckStatus(l.get(0).getCheckStatus());
            e.setJobStatus(l.get(0).getJobStatus());
        } else {
            if (isNew) {
                e.setPushflag(PUSHFLAG_NOT);
                e.setReviewStatus("0");
                e.setCheckStatus("0");
                if (StringUtils.isEmpty(e.getIdentifyFlag()))
                    e.setIdentifyFlag("01");
            }
        }
        
        if (StringUtils.isEmpty(e.getEmployeeCode()) || e.getOp() == MetaData.OP_UPD) {
            e = (CompanyEmployee) super.save(e);
        }

        e.setDeptCode(deptCode);
        e.setCompanyCode(companyCode);
        e.setLinkId(linkId);

        // 插入部门关系表
        TDeptEmployee dpe;
        if (isNew) {
            dpe = new TDeptEmployee();
            dpe.setEmployeeCode(e.getEmployeeCode());
            dpe.setDeptCode(deptCode);
            dpe.setCompanyCode(companyCode);
            dao.save(dpe);
            e.setLinkId(dpe.getId());
        } else {
            dpe = dao.get(TDeptEmployee.class, e.getLinkId());
            dpe.setEmployeeCode(e.getEmployeeCode());
            dpe.setDeptCode(deptCode);
            dpe.setCompanyCode(companyCode);
            dao.update(dpe);
            e.setLinkId(dpe.getId());
        }

        // 人员操作记录
        if (isNew) {
			TCompanyEmployee ce = dao.get(TCompanyEmployee.class, e.getEmployeeCode());
			ce.setJobStatus("1");		//入职
			dao.update(ce);
        	
            TEmployeeOperate eo = new TEmployeeOperate();
            eo.setCompanyCode(companyCode);
            eo.setDeptCode(deptCode);
            eo.setEmployeeCode(e.getEmployeeCode());
            eo.setOpType("1");// 入职
            eo.setOpTime(new Timestamp(new Date().getTime()));
            eo.setOpUserid(u.getId());
            dao.save(eo);
        }

        // 人员认证
        if (dao.list(TAccountIdentity.class, new ORQuery(Op.eq, "employeeCode", e.getEmployeeCode())).size() > 0)
            e.setIdentifyFlag(ConstantUtil.IDENTIFYFLAG_OK);

        // 在account表中添加 Employeecode信息
        List<ORQuery> qAccountInfo = new ArrayList<ORQuery>();
//		qAccountInfo.add(new ORQuery(Op.eq, "fullname", e.getFullname()));
        qAccountInfo.add(new ORQuery(Op.eq, "papersNumber", e.getPapersNumber()));
        qAccountInfo.add(new ORQuery(Op.eq, "papersType", e.getPapersType()));
        for (TAccountIdentity ai : dao.list(TAccountIdentity.class, qAccountInfo)) {
            ai.setEmployeeCode(e.getEmployeeCode());
            dao.update(ai);
        }

        return e;
    }

    @Override
    public Object del(MetaData data) throws Exception {
        CompanyEmployee e = (CompanyEmployee) data;

        Map<String, String> map = new HashMap<>();
        map.put("employeeCode", e.getEmployeeCode());
        List<CompanyEmployee> empList = (List<CompanyEmployee>) this.list(map);
        List<TUser> listu = dao.list(TUser.class, new ORQuery(Op.eq, "employeeCode", e.getEmployeeCode()));
        if (empList.size() == 1 && listu.size() > 0) {
            for (TUserRole ur : dao.list(TUserRole.class, new ORQuery(Op.eq, "userid", listu.get(0).getId()))) {
                String roleId = ur.getRoleid();
                String roleName = "";
                TRole role = dao.get(TRole.class, roleId);
                if (role != null) {
                    roleName = role.getName();
                }
                throw new Exception("该人员是'" + roleName + "',请先撤除此权限");
//              dao.delete(ur);
            }
        }

        List<ORQuery> querys = new ArrayList<ORQuery>();
        querys.add(new ORQuery(Op.eq, "employeeCode", e.getEmployeeCode()));
        if (StringUtils.isEmpty(e.getDeptCode())) {
            querys.add(new ORQuery(Op.isnull, "deptCode", null));
        } else {
            querys.add(new ORQuery(Op.eq, "deptCode", e.getDeptCode()));
        }
        querys.add(new ORQuery(Op.eq, "companyCode", e.getCompanyCode()));
        List<TDeptEmployee> list = dao.list(TDeptEmployee.class, querys);
        // if (list.size() != 1)throw new Exception("删除失败！");
        for (TDeptEmployee x : list) {
            dao.delete(x);
            User u = (User) ServiceContext.getInstance().getUser();
            TEmployeeOperate op = new TEmployeeOperate();
            op.setOpType(OPTYPE_DEPART);
            op.setEmployeeCode(e.getEmployeeCode());
            op.setCompanyCode(e.getCompanyCode());
            op.setDeptCode(e.getDeptCode());
            op.setOpTime(new Timestamp(new Date().getTime()));
            op.setOpUserid(u.getId());
            dao.save(op);
        }
        
        //如果用户从所有企业中都离职时，则清除用户的通行证和审批状态
        querys.clear();
        querys.add(new ORQuery(Op.eq, "employeeCode", e.getEmployeeCode()));
        List<TDeptEmployee> deptEmployeeList = dao.list(TDeptEmployee.class, querys);
        List<TEmployeeContractorDept> employeeContractorDeptList = dao.list(TEmployeeContractorDept.class, querys);
        if (deptEmployeeList.size() == 0 && employeeContractorDeptList.size() == 0) {
        	TCompanyEmployee companyEmployee= dao.get(TCompanyEmployee.class, e.getEmployeeCode());
        	if (companyEmployee != null) {
        		companyEmployee.setIssueNo(null);
        		companyEmployee.setEndExpirydate(null);
        		companyEmployee.setCheckStatus("0");
        		companyEmployee.setJobStatus("2");
        		dao.update(companyEmployee);
        	}
        	
        	//清除用户所属车辆的通行证和审批状态
            querys.clear();
            querys.add(new ORQuery(Op.eq, "employeeCode", e.getEmployeeCode()));
            List<TVehicleInfo> vehicleInfoList = dao.list(TVehicleInfo.class, querys);
            for (TVehicleInfo vehicleInfo: vehicleInfoList) {
            	vehicleInfo.setIssueNo(null);
            	vehicleInfo.setEndExpirydate(null);
            	vehicleInfo.setCheckStatus("0");
        		dao.update(vehicleInfo);
            }
        }
        
        return data;
    }

}
